<template>
  <div class="overlay-analysis-container">
    <div id="map" class="map-container" v-loading="loading" element-loading-text="正在分析中..."></div>
    <div class="overlay-analysis">
      <el-card class="analysis-panel">
        <template #header>
          <div class="card-header">
            <span>叠加分析示例</span>
          </div>
        </template>

        <el-form :model="formData" label-width="100px">
          <el-form-item label="叠加类型">
            <el-select v-model="formData.overlayType" placeholder="选择叠加类型">
              <el-option label="求交" value="intersection" />
              <el-option label="求并" value="union" />
              <el-option label="求差" value="difference" />
            </el-select>
          </el-form-item>

          <el-form-item label="绘制图层">
            <el-radio-group v-model="activeLayer">
              <el-radio-button label="layer1">图层1</el-radio-button>
              <el-radio-button label="layer2">图层2</el-radio-button>
            </el-radio-group>
          </el-form-item>

          <div class="button-container">
            <el-button-group>
              <el-button type="primary" @click="startDraw">
                <el-icon><Edit /></el-icon>
                绘制多边形
              </el-button>
              <el-button type="success" @click="performOverlayAnalysis" :disabled="!canAnalyze"> 执行分析 </el-button>
              <el-button type="warning" @click="clearAnalysis">清除分析</el-button>
            </el-button-group>
          </div>

          <div class="analysis-result" v-if="analysisResult">
            <el-divider>分析结果</el-divider>
            <p>叠加类型：{{ formData.overlayType }}</p>
            <p>结果要素数量：{{ analysisResult.featureCount }} 个</p>
          </div>
        </el-form>
      </el-card>
    </div>
  </div>
</template>

<script setup>
import { reactive, ref, onMounted, computed } from "vue";
import { ElMessage } from "element-plus";
import { Edit } from "@element-plus/icons-vue";
import { Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer } from "ol/layer";
import { Draw } from "ol/interaction";
import { Style, Fill, Stroke } from "ol/style";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import { fromLonLat } from "ol/proj";
import * as turf from "@turf/turf";
import { intersect } from "@turf/intersect";

import GeoJSON from "ol/format/GeoJSON";

const mapInstance = ref(null);
const baseLayer = ref(null);
const overlaySource1 = ref(null);
const overlaySource2 = ref(null);
const resultSource = ref(null);
const analysisResult = ref(null);
const loading = ref(false);
const activeLayer = ref("layer1");
const draw = ref(null);

const formData = reactive({
  overlayType: "intersection",
});

// 检查是否可以执行分析
const canAnalyze = computed(() => {
  return overlaySource1.value?.getFeatures().length > 0 && overlaySource2.value?.getFeatures().length > 0;
});

// 开始绘制
const startDraw = () => {
  // 移除现有的绘制交互
  if (draw.value) {
    mapInstance.value.removeInteraction(draw.value);
  }

  // 创建新的绘制交互
  draw.value = new Draw({
    source: activeLayer.value === "layer1" ? overlaySource1.value : overlaySource2.value,
    type: "Polygon",
  });

  // 添加绘制交互到地图
  mapInstance.value.addInteraction(draw.value);

  ElMessage.info(`开始在${activeLayer.value === "layer1" ? "图层1" : "图层2"}上绘制多边形`);
};

const performOverlayAnalysis = async () => {
  if (!canAnalyze.value) {
    ElMessage.warning("请确保两个图层都有多边形");
    return;
  }

  try {
    loading.value = true;
    const features1 = overlaySource1.value.getFeatures();
    const features2 = overlaySource2.value.getFeatures();

    // 修改几何对象的转换方式
    const polygon1 = features1[0].getGeometry().clone().transform("EPSG:3857", "EPSG:4326");
    const polygon2 = features2[0].getGeometry().clone().transform("EPSG:3857", "EPSG:4326");

    console.log(polygon1);

    const turfPoly1 = turf.polygon([polygon1.getCoordinates()[0]]);
    const turfPoly2 = turf.polygon([polygon2.getCoordinates()[0]]);

    // 验证多边形
    if (!turf.booleanValid(turfPoly1) || !turf.booleanValid(turfPoly2)) {
      console.error("Invalid polygons for overlay analysis.");
      ElMessage.error("多边形数据无效，无法进行叠加分析");
      return;
    }

    // console.log(turfPoly1, turfPoly2);

    let resultFeatures = [];
    switch (formData.overlayType) {
      case "intersection":
        try {
          const intersection = intersect(turf.featureCollection([turfPoly1, turfPoly2]));
          resultFeatures = intersection ? [intersection] : [];
        } catch (error) {
          console.error("Intersection Error:", error);
        }
        break;
      case "union":
        resultFeatures = [turf.union(turf.featureCollection([turfPoly1, turfPoly2]))];
        break;
      case "difference":
        const difference = turf.difference(turf.featureCollection([turfPoly1, turfPoly2]));
        resultFeatures = difference ? [difference] : [];
        break;
    }

    console.log("Result Features:", resultFeatures);

    if (resultFeatures.length > 0) {
      resultSource.value.clear();
      const olFeatures = resultFeatures.map((feature) =>
        new GeoJSON().readFeature(feature, {
          dataProjection: "EPSG:4326",
          featureProjection: "EPSG:3857",
        })
      );
      resultSource.value.addFeatures(olFeatures);
      analysisResult.value = { featureCount: resultFeatures.length };
      ElMessage.success("叠加分析完成");
    } else {
      ElMessage.warning("未找到叠加结果");
    }
  } catch (error) {
    console.error("叠加分析出错:", error);
    ElMessage.error("叠加分析失败，请重试");
  } finally {
    loading.value = false;
  }
};

const clearAnalysis = () => {
  if (draw.value) {
    mapInstance.value.removeInteraction(draw.value);
    draw.value = null;
  }
  overlaySource1.value.clear();
  overlaySource2.value.clear();
  resultSource.value.clear();
  analysisResult.value = null;
};

onMounted(() => {
  baseLayer.value = new TileLayer({
    source: new OSM(),
    zIndex: 0,
  });

  overlaySource1.value = new VectorSource();
  overlaySource2.value = new VectorSource();
  resultSource.value = new VectorSource();

  const overlayLayer1 = new VectorLayer({
    source: overlaySource1.value,
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 0, 0, 0.3)",
      }),
      stroke: new Stroke({
        color: "#ff0000",
        width: 2,
      }),
    }),
    zIndex: 1,
  });

  const overlayLayer2 = new VectorLayer({
    source: overlaySource2.value,
    style: new Style({
      fill: new Fill({
        color: "rgba(0, 0, 255, 0.3)",
      }),
      stroke: new Stroke({
        color: "#0000ff",
        width: 2,
      }),
    }),
    zIndex: 2,
  });

  const resultLayer = new VectorLayer({
    source: resultSource.value,
    style: new Style({
      fill: new Fill({
        color: "rgba(0, 255, 0, 0.3)",
      }),
      stroke: new Stroke({
        color: "#00ff00",
        width: 2,
      }),
    }),
    zIndex: 3,
  });

  mapInstance.value = new Map({
    target: "map",
    layers: [baseLayer.value, overlayLayer1, overlayLayer2, resultLayer],
    view: new View({
      center: fromLonLat([120.1552, 30.2417]),
      zoom: 12,
      maxZoom: 18,
      minZoom: 2,
    }),
  });
});
</script>

<style scoped>
.overlay-analysis-container {
  width: 100%;
  height: 100vh;
  position: relative;
}

.map-container {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.overlay-analysis {
  padding: 15px;
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 1000;
}

.analysis-panel {
  max-width: 400px;
  background-color: rgba(255, 255, 255, 0.95);
}

.card-header {
  font-weight: bold;
}

.button-container {
  display: flex;
  justify-content: center;
  margin: 20px 0;
  width: 100%;
}

:deep(.el-button-group) {
  display: flex;
  width: 100%;
}

:deep(.el-button-group .el-button) {
  flex: 1;
}

:deep(.el-form-item) {
  margin-bottom: 20px;
}

:deep(.el-radio-group) {
  width: 100%;
  display: flex;
}

:deep(.el-radio-button) {
  flex: 1;
}

:deep(.el-radio-button__inner) {
  width: 100%;
}

:deep(.el-form-item__content) {
  display: flex;
  justify-content: center;
  width: 100%;
}

:deep(.el-select) {
  width: 100%;
}

.analysis-result {
  margin-top: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.analysis-result p {
  margin: 8px 0;
  color: #606266;
}

.el-divider {
  margin: 16px 0;
}
</style>
